嗨,昨天完成了一項實戰後,今天來看如何透過Scrapy模擬登入,有些內容是需要登入後才可以看到,這裡有一個範例的網頁: Quotes to Scrape


(Goodreads page)不見了。
現在,回到剛剛的登入頁面,點右鍵檢查:
<form>元素,點擊Login按鈕後,瀏覽器會根據<form>元素的內容發送HTTP請求,可以看到該表單method為post請求方法,action為請求的url。<input>元素,可以看到name為username及password對應到兩個輸入框:
上面有一個<input type="hidden" name="csrf_token">,每重新整理一次頁面,它的value都會改變,雖然它的值不需要使用者填寫,但是在傳送表單的時候缺少就會造成登入驗證失敗,也就是說我們需要先得到這串資訊,就必須登入前先爬取它(token),再把username, password透過FormRequest()將一並代入,如下程式碼:
import scrapy
from bs4 import BeautifulSoup
class NewsSpider(scrapy.Spider):
name = "quotes"
start_urls = ['http://quotes.toscrape.com/login']
def parse(self, response):
token = response.css("input[name='csrf_token']::attr('value')").extract_first()
# print(token)
data = {
'csrf_token':token,
'username':'user',
'password':'123'
}
yield scrapy.FormRequest(url=self.start_urls[0], formdata=data, callback=self.parse_quotes)
def parse_quotes(self, response):
soup = BeautifulSoup(response.text)
quotes = soup.select('div.quote')
for q in quotes:
print(q.select('a'))
假設我們直接在Quotes to Scrape頁面直接爬(例如以下程式碼),會發現結果會沒有包含(Goodreads page)內容:
class NewsSpider(scrapy.Spider):
name = "quotes"
start_urls = ['http://quotes.toscrape.com/']
def parse(self, response):
soup = BeautifulSoup(response.text)
quotes = soup.select('div.quote')
for q in quotes:
print(q.select('a'))
好的,這就是模擬登入了的說明了!那我們明天見啦!